﻿//#include <iostream>
//using namespace std;
//const int MOD = 1e9 + 7;
//int n;
//int main()
//{
//	cin >> n;
//	int x = 1, y = 2;
//	for (int i = 2; i <= n; i++)
//	{
//		int xx = x, yy = y;
//		x = (2 * yy + 1) % MOD;
//		y = ((2 * yy) % MOD + 2 + xx) % MOD;
//	}
//	cout << x << " " << y << endl;
//	return 0;
//}


//
//const int N = 15, M = 1010;
//int n, arr[N];
//bool use[M]; 
//int path; 
//int ret = 0x3f3f3f3f;
//bool isPrim(int x)
//{
//	if (x <= 1) return false;
//	for (int i = 2; i <= sqrt(x); i++)
//	{
//		if (x % i == 0) return false;
//	}
//	return true;
//}
//void dfs(int pos)
//{
//	if (pos == n)
//	{
//		ret = min(ret, path);
//		return;
//	}
//
//	// 枚举 arr[pos] 的所有没有使⽤过的素因⼦
//	for (int i = 2; i <= arr[pos]; i++)
//	{
//		if (arr[pos] % i == 0 && isPrim(i) && !use[i])
//		{
//			path += i;
//			use[i] = true;
//			dfs(pos + 1);
//			// 回溯 - 恢复现场
//			path -= i;
//			use[i] = false;
//		}
//	}
//}
//int main()
//{
//	cin >> n;
//	for (int i = 0; i < n; i++) cin >> arr[i];
//
//	dfs(0);
//
//	if (ret == 0x3f3f3f3f) cout << -1 << endl;
//	else cout << ret << endl;
//
//	return 0;
//}




#include <iostream>
#include <string>
using namespace std;
const int N = 1e6 + 10;
int n;
string s;
char dp[N]; // dp[i] 表⽰：⻓度为 i 的所有的⼦序列中，最⼩的末尾是多少
int ret;
int main()
{
	cin >> n >> s;
	for (int i = 0; i < n; i++)
	{
		char ch = s[i];
		// 找出 ch 应该放在哪个位置
		if (ret == 0 || ch >= dp[ret])
		{
			dp[++ret] = ch;
		}
		else
		{
			// ⼆分出 ch 应该放的位置
			int left = 1, right = ret;
			while (left < right)
			{
				int mid = (left + right) / 2;
				if (dp[mid] > ch) right = mid;
				else left = mid + 1;
			}
			dp[left] = ch;
		}
	}

	cout << n - ret << endl;

	return 0;
}